package client;

import java.nio.file.Path;
import java.util.HashMap;

import shared.*;

public class LocalEventHandler implements Runnable {
	private Client client;

	public LocalEventHandler(Client client) {
		this.client = client;
	}

	/**
	 * Four Cases: 
	 * 01: file not in localList but in traversed list 
	 * 10: file in localList but not in traversed list 
	 * 11: file both in localList and traversed list
	 * 
	 * @throws InterruptedException
	 */
	public void detectEvents()  {
		Toolkit.getInstance().traverse(Configuration.getHomePath().toString());
		
		
		HashMap<String, FileDescriptor> traversedList = Toolkit.getInstance()
				.getTraversedFiles();
		HashMap<String, FileDescriptor> localList = this.client.currentUser.myFiles;

		HashMap<String, char[]> occurMap = Toolkit.getInstance().mergeKey(
				localList, traversedList);

		for (String file : occurMap.keySet()) {
			String occurence = new String(occurMap.get(file));
			if (occurence.equals("01")) {
				// new file create locally
				FileDescriptor newFd = traversedList.get(file);
				if(client.currentUser.myFiles.get(file) !=null){
					//time of use time of check
					System.err.println("time of check !!");
					return;
				}
				
				Path path = Configuration.getHomePath().resolve(file);
				newFd.setHash(Utilities.computeHash(path.toString()));
				try {
					client.myfilesLock.acquire();
					if(client.currentUser.myFiles.get(file)==null){
						localList.put(file, newFd);
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					client.myfilesLock.release();
				}
				
				System.out.println(newFd + "  Create-Event");
			}

			else if (occurence.equals("10")) {
				// File Deleted Locally
				FileDescriptor localFile = localList.get(file);
				try {
					client.myfilesLock.acquire();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				localFile.setDeletedLocal(true);
				client.myfilesLock.release();
				System.out.println(localFile + "  Deleted-Event");
			}

			else if (occurence.equals("11")) {
				// File both exist
				FileDescriptor actualFile = traversedList.get(file);
				if (actualFile.isDirectory()){
					continue;
				}
				
				try {
					client.myfilesLock.acquire();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				Path path = Configuration.getHomePath().resolve(file);
				actualFile.setHash(Utilities.computeHash(path.toString()));
				FileDescriptor localFile = client.currentUser.myFiles.get(file);

				if (!localFile.getHash().equals(actualFile.getHash())) {		
					localFile.setModifiedLocal(true);
					localFile.setHash(actualFile.getHash());	
					System.out.println(localFile + "  Modified-Event");
				}
				client.myfilesLock.release();
				
			} else {
				System.err.println("Fatal Error: undefined condition");
			}
		}

	}

	@Override
	public void run() {

		try {
			while (true) {

				this.detectEvents();
				Thread.sleep(Configuration.TRAVERSE_PERIOD);
			}
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
	}

}
